package MemTrac::Utils;
use strict;
use Time::Local;

require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw( compile_template datetime2epoch make_duration clean_string );
our @EXPORT_OK = qw();

sub compile_template {
	my ($str,$nostrip)=@_;
	my $code;

	$str=~s/^\s+//;
	$str=~s/\s+$//;
#	$str=~s/\n\s*/ /sg unless $nostrip;

	while($str=~m!(.*?)(<(/?)(var|const|if|loop)(?:|\s+(.*?[^\\]))>|$)!sg)
	{
		my ($html,$tag,$closing,$name,$args)=($1,$2,$3,$4,$5);
		
		$args="" unless($args);

		$html=~s/(['\\])/\\$1/g;
		$code.="\$res.='$html';" if(length $html);
		$args=~s/\\>/>/g;

		if($tag)
		{
			if($closing)
			{
				if($name eq 'if') { $code.='}' }
				elsif($name eq 'loop') { $code.='$$_=$__ov{$_} for(keys %__ov);}}' }
			}
			else
			{
				if($name eq 'var') { $code.='$res.=eval{'.$args.'};' }
				elsif($name eq 'const') { my $const=eval $args; $const=~s/(['\\])/\\$1/g; $code.='$res.=\''.$const.'\';' }
				elsif($name eq 'if') { $code.='if(eval{'.$args.'}){' }
				elsif($name eq 'loop')
				{ $code.='my $__a=eval{'.$args.'};if($__a){for(@$__a){my %__v=%{$_};my %__ov;for(keys %__v){$__ov{$_}=$$_;$$_=$__v{$_};}' }
			}
		}
	}

	my $sub=eval
		'no strict; sub { '.
		'my $port=$ENV{SERVER_PORT}==80?"":":$ENV{SERVER_PORT}";'.
		'my $self=$ENV{SCRIPT_NAME};'.
		'my $absolute_self="http://$ENV{SERVER_NAME}$port$ENV{SCRIPT_NAME}";'.
		'my ($path)=$ENV{SCRIPT_NAME}=~m!^(.*/)[^/]+$!;'.
		'my $absolute_path="http://$ENV{SERVER_NAME}$port$path";'.
		'my %__v=@_;my %__ov;for(keys %__v){$__ov{$_}=$$_;$$_=$__v{$_};}'.
		'my $res;'.
		$code.
		'$$_=$__ov{$_} for(keys %__ov);'.
		'return $res; }';

	die "Template format error" unless($sub);

	return $sub;
}

sub clean_string {
	my ($str)=@_;

	$str=~s/[\x00-\x08\x0b\x0c\x0e-\x1f]//g; # remove control chars

	$str=~s/&/&amp;/g;
	$str=~s/\</&lt;/g;
	$str=~s/\>/&gt;/g;
	$str=~s/"/&quot;/g;
	$str=~s/'/&#39;/g;
	$str=~s/,/&#44;/g;

	# repair unicode entities
	$str=~s/&amp;(\#[0-9]+;)/&$1/g;
	$str=~s/&amp;(\#x[0-9a-f]+;)/&$1/gi;

	return $str;
}

sub datetime2epoch {
    my ($datetime) = @_;
    $datetime =~ m/^(....)-(..)-(..) (..):(..):(..)$/;
    
    return timelocal($6, $5, $4, $3, ($2-1), $1);
}

sub make_duration($$) {
	my ($time1,$time2)=@_;
	my @days=qw(Sun Mon Tue Wed Thu Fri Sat);
	my ($dur,$w,$d,$h,$m,$durs);
	
	$w=$d=$h=$m=0;
	
	if($time1>$time2) {
	$dur = $time1-$time2;
	} else {
	$dur = $time2-$time1;
	}
	
	my $dur2 = $dur;
	
	if($dur>604800) { $w = $dur/604800; $w =~ s/\.[0-9]*//g; $dur=$dur - ($w * 604800); }
	if($dur>86400) { $d = $dur/86400; $d =~ s/\.[0-9]*//g; $dur=$dur - ($d * 86400); }
	if($dur>3600) { $h = $dur/3600; $h =~ s/\.[0-9]*//g; $dur=$dur - ($h * 3600); }
	if($dur>60) { $m = $dur/60; $m =~ s/\.[0-9]*//g;}
	
	$durs = "00m";
	if($dur2>60) { $durs = sprintf("%02d",$m) ."m "; }
	if($dur2>3600) { $durs = sprintf("%02d",$h) ."h " . sprintf("%02d",$m) ."m "; }
	if($dur2>86400) { $durs = $d ."d " . sprintf("%02d",$h) ."h "; }
	if($dur2>604800) { $durs = $w ."w " . $d ."d "; }
	
    $durs =~ s/ $//;
    
	return $durs;
}

sub last_seen {
	my ($time1,$time2) = @_;
	
	if ( $time1 > $time2 ) {
		return make_duration($time1,time());
	}
	else {
		return make_duration($time2,time());
	}
}

sub seen_for {
	my ($time1,$time2) = @_;
	
	if ( $time1 > $time2 ) {
		return "";
	}
	else {
		return make_duration($time2,$time1);
	}
}

1;
